import { describe, expect, test } from 'vitest';
import {
  type AreaTypeNode,
  areaNodeMap,
  areaNodes,
  createAreaTree,
  formatAreaToNode,
} from '../../src/hammer/area/area.mts';

describe('区域相关功能测试', () => {
  describe('formatAreaToNode', () => {
    test('应该正确格式化区域数据为树节点', () => {
      const result = formatAreaToNode();

      expect(Array.isArray(result)).toBe(true);
      expect(result.length).toBeGreaterThan(0);

      // 检查第一个区域节点
      const firstArea = result[0];
      expect(firstArea).toHaveProperty('name');
      expect(firstArea).toHaveProperty('code');
      expect(firstArea).toHaveProperty('id');
      expect(firstArea).toHaveProperty('parent');
      expect(firstArea.id).toBe(firstArea.code);
    });

    test('应该正确设置父子关系', () => {
      const result = formatAreaToNode();

      // 找到北京市
      const beijing = result.find((area) => area.name === '北京市');
      expect(beijing).toBeDefined();
      expect(beijing?.parent).toBeNull();

      // 检查北京市的子节点
      if (beijing?.children) {
        beijing.children.forEach((child) => {
          expect(child.parent).toBe(beijing);
        });
      }
    });
  });

  describe('areaNodes', () => {
    test('应该是预先格式化的区域节点数组', () => {
      expect(Array.isArray(areaNodes)).toBe(true);
      expect(areaNodes.length).toBeGreaterThan(0);

      // 检查节点结构
      areaNodes.forEach((node) => {
        expect(node).toHaveProperty('name');
        expect(node).toHaveProperty('code');
        expect(node).toHaveProperty('id');
        expect(typeof node.name).toBe('string');
        expect(typeof node.code).toBe('string');
        expect(typeof node.id).toBe('string');
      });
    });
  });

  describe('areaNodeMap', () => {
    test('应该返回Map实例', () => {
      const map = areaNodeMap();
      expect(map).toBeDefined();
      expect(map instanceof Map).toBe(true);
    });
  });

  describe('createAreaTree', () => {
    test('应该创建区域树实例', () => {
      const areaTree = createAreaTree();

      expect(areaTree).toBeDefined();
      expect(Array.isArray(areaTree.value)).toBe(true);
      expect(areaTree.value.length).toBeGreaterThan(0);
    });

    test('应该具有正确的根节点数量', () => {
      const areaTree = createAreaTree();

      expect(areaTree.rootCount).toBe(areaTree.value.length);
      expect(typeof areaTree.rootCount).toBe('number');
      expect(areaTree.rootCount).toBeGreaterThan(0);
    });

    test('应该正确判断是否为单根节点', () => {
      const areaTree = createAreaTree();

      expect(typeof areaTree.isOneRoot).toBe('boolean');
      expect(areaTree.isOneRoot).toBe(areaTree.rootCount === 1);
    });

    test('应该正确判断是否为根节点', () => {
      const areaTree = createAreaTree();

      // 第一个节点应该是根节点
      const firstRoot = areaTree.value[0];
      expect(areaTree.isRoot(firstRoot)).toBe(true);

      // 非根节点（子节点）
      if (firstRoot.children && firstRoot.children.length > 0) {
        const child = firstRoot.children[0];
        expect(areaTree.isRoot(child)).toBe(false);
      }
    });

    test('应该能遍历所有区域节点', () => {
      const areaTree = createAreaTree();
      const visitedNodes: AreaTypeNode[] = [];

      areaTree.traverseTree((node) => {
        visitedNodes.push(node);
      });

      expect(visitedNodes.length).toBeGreaterThan(0);

      // 检查遍历到的节点
      visitedNodes.forEach((node) => {
        expect(node).toHaveProperty('name');
        expect(node).toHaveProperty('code');
        expect(typeof node.name).toBe('string');
        expect(typeof node.code).toBe('string');
      });
    });

    test('应该能获取树的深度', () => {
      const areaTree = createAreaTree();
      const depth = areaTree.getTreeDepth();

      expect(typeof depth).toBe('number');
      expect(depth).toBe(3);
      expect(depth).toBeGreaterThan(0);

      // 区域数据通常有省市区三级，所以深度应该至少为3
      expect(depth).toBeGreaterThanOrEqual(2);
    });

    test('应该能获取所有叶子节点', () => {
      const areaTree = createAreaTree();
      const leafNodes = areaTree.getTreeLeaf();

      expect(Array.isArray(leafNodes)).toBe(true);
      expect(leafNodes.length).toBeGreaterThan(0);

      // 所有叶子节点都不应该有子节点
      leafNodes.forEach((node) => {
        expect(!node.children || node.children.length === 0).toBe(true);
      });
    });

    test('应该能通过ID查找节点', () => {
      const areaTree = createAreaTree();

      // 查找北京市
      const beijing = areaTree.getTreeNode('110000');
      expect(beijing).toBeDefined();
      expect(beijing?.name).toBe('北京市');

      // 查找河北省
      const hebei = areaTree.getTreeNode('130000');
      expect(hebei).toBeDefined();
      expect(hebei?.name).toBe('河北省');

      // 查找不存在的节点
      const notFound = areaTree.getTreeNode('999999');
      expect(notFound).toBeUndefined();
    });

    test('应该能获取节点的路径', () => {
      const areaTree = createAreaTree();

      // 获取东城区的路径
      const dongcheng = areaTree.getTreeNode('110101');
      expect(dongcheng).toBeDefined();

      if (dongcheng) {
        const path = areaTree.getTreePath(dongcheng);
        expect(Array.isArray(path)).toBe(true);
        expect(path.length).toBeGreaterThan(0);

        // 路径应该从根节点到目标节点
        expect(path[0].parent).toBeNull(); // 根节点
        expect(path[path.length - 1]).toBe(dongcheng); // 目标节点

        // 检查路径连续性
        for (let i = 1; i < path.length; i++) {
          expect(path[i].parent).toBe(path[i - 1]);
        }
      }
    });

    test('应该能获取叶子节点映射', () => {
      const areaTree = createAreaTree();
      const leafMap = areaTree.getTreeLeafNodeMap();

      expect(leafMap).toBeInstanceOf(Map);
      expect(leafMap.size).toBeGreaterThan(0);

      // 所有值都应该是叶子节点
      leafMap.forEach((node) => {
        expect(!node.children || node.children.length === 0).toBe(true);
      });
    });

    test('应该返回区域树实例', () => {
      const tree = createAreaTree();

      // 应该返回有效的区域树实例
      expect(tree).toBeDefined();
      expect(tree.value).toBeDefined();
      expect(tree.value.length).toBeGreaterThan(0);
    });

    test('应该能创建树实例', () => {
      const tree = createAreaTree();

      // 应该返回有效的树实例
      expect(tree).toBeDefined();
      expect(tree.value).toBeDefined();
      expect(tree.value.length).toBeGreaterThan(0);
      expect(tree.getTreeDepth()).toBeGreaterThan(0);
    });
  });

  describe('边界情况测试', () => {
    test('应该处理空区域数据', () => {
      // 这个测试需要mock数据，但在当前实现中无法mock
      // 所以主要验证现有数据的完整性
      const areaTree = createAreaTree();

      expect(areaTree.value.length).toBeGreaterThan(0);
      expect(areaTree.getTreeDepth()).toBeGreaterThan(0);
    });

    test('应该处理深层嵌套的区域结构', () => {
      const areaTree = createAreaTree();
      const depth = areaTree.getTreeDepth();

      // 区域数据通常有省市区三级结构
      expect(depth).toBeGreaterThanOrEqual(2);
      expect(depth).toBeLessThanOrEqual(5); // 应该不会太深
    });

    test('应该正确处理区域代码的唯一性', () => {
      const map = areaNodeMap();
      const codes = Array.from(map.keys());

      // 所有区域代码应该是唯一的
      const uniqueCodes = new Set(codes);
      expect(uniqueCodes.size).toBe(codes.length);

      // 检查代码格式（应该是6位数字字符串）
      codes.forEach((code) => {
        expect(code).toMatch(/^\d{6}$/);
      });
    });
  });

  describe('实际区域数据验证', () => {
    test('应该包含主要省级行政区', () => {
      const areaTree = createAreaTree();

      // 检查主要省级行政区
      const provinceNames = areaTree.value.map((node) => node.name);

      expect(provinceNames).toContain('北京市');
      expect(provinceNames).toContain('天津市');
      expect(provinceNames).toContain('河北省');
    });

    test('应该正确建立省市区层级关系', () => {
      const areaTree = createAreaTree();

      // 找到河北省
      const hebei = areaTree.value.find((node) => node.name === '河北省');
      expect(hebei).toBeDefined();
      expect(hebei?.parent).toBeNull();

      if (hebei?.children) {
        // 河北省应该有多个地级市
        expect(hebei.children.length).toBeGreaterThan(0);

        // 找到石家庄市
        const shijiazhuang = hebei.children.find(
          (child) => child.name === '石家庄市',
        );
        expect(shijiazhuang).toBeDefined();
        expect(shijiazhuang?.parent).toBe(hebei);

        if (shijiazhuang?.children) {
          // 石家庄市应该有多个区县
          expect(shijiazhuang.children.length).toBeGreaterThan(0);
        }
      }
    });

    test('应该能找到主要区域节点', () => {
      const areaTree = createAreaTree();

      // 省级
      const beijing = areaTree.getTreeNode('110000');
      expect(beijing?.name).toBe('北京市');

      // 检查是否有市级节点
      const node130100 = areaTree.getTreeNode('130100');
      expect(node130100).toBeDefined();

      // 检查是否有区县级节点
      const node110105 = areaTree.getTreeNode('110105');
      expect(node110105).toBeDefined();
    });
  });
});
